package 力扣_链表.面试常考.环形链表;

import java.util.HashMap;
import java.util.Map;

public class 寻找重复数 {
    /**
     * 面试写法：时间复杂度 O(N), 空间复杂度 O(1)
     * 思路看下面的文章,讲的非常棒：
     * https://leetcode.cn/problems/find-the-duplicate-number/solutions/2833858/cong-er-fen-cha-zhao-dao-kuai-man-zhi-zh-ixa3/
     *
     * 同一博主的环形链表II写法：
     * https://leetcode.cn/problems/linked-list-cycle-ii/solutions/2832831/jian-ji-qing-xi-yan-jin-de-tu-shi-tui-da-nak2/
     */
    public int findDuplicate(int[] nums) {
        int slow = 0, fast = 0;
        while (true) {
            // 快慢指针：fast前进两次, slow前进一次
            fast = nums[fast];
            fast = nums[fast];
            slow = nums[slow];
            if (slow == fast) {
                break;
            }
        }
        // ptr == slow 时说明检测到重复元素，两个重复元素同时指向环的入口
        int ptr = 0;
        while (ptr != slow) {
            ptr = nums[ptr];
            slow = nums[slow];
        }
        return ptr;
    }

    public int findDuplicate2(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0;i < nums.length;i++){
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
        }
        for(Map.Entry<Integer, Integer> entry : map.entrySet()){
            if(entry.getValue() > 1){
                return entry.getKey();
            }
        }
        return 0;
    }
}
